package com.ygqh.baby.service.task.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.ygqh.baby.ao.BalanceType;
import com.ygqh.baby.ao.CommissionStatus;
import com.ygqh.baby.ao.CouponStatus;
import com.ygqh.baby.ao.OperationType;
import com.ygqh.baby.ao.RebateType;
import com.ygqh.baby.mapper.YgUserBalanceDetailMapper;
import com.ygqh.baby.po.YgCoupon;
import com.ygqh.baby.po.YgCouponDetail;
import com.ygqh.baby.po.YgOrder;
import com.ygqh.baby.po.YgReturnOrder;
import com.ygqh.baby.po.YgUser;
import com.ygqh.baby.po.YgUserBalance;
import com.ygqh.baby.po.YgUserBalanceDetail;
import com.ygqh.baby.service.WxMpAuthorityService;
import com.ygqh.baby.service.WxMpMessageService;
import com.ygqh.baby.service.YgCouponDetailService;
import com.ygqh.baby.service.YgCouponService;
import com.ygqh.baby.service.YgOrderService;
import com.ygqh.baby.service.YgReturnOrderService;
import com.ygqh.baby.service.YgTaskTimeService;
import com.ygqh.baby.service.YgUserBalanceDetailService;
import com.ygqh.baby.service.YgUserBalanceService;
import com.ygqh.baby.service.YgUserService;
import com.ygqh.baby.service.task.YgRepairDataService;
import com.ygqh.baby.utils.YgStringUtils;

@Service
public class YgRepairDataServiceImpl implements YgRepairDataService {
	protected final Logger logger = Logger.getLogger(this.getClass());
	@Autowired
	YgOrderService ygOrderService;
	@Autowired
	YgReturnOrderService ygReturnOrderService;
	@Autowired
	YgUserBalanceDetailMapper ygUserBalanceDetailMapper;
	@Autowired
	YgUserBalanceService ygUserBalanceService;
	@Autowired
	YgUserBalanceDetailService ygUserBalanceDetailService;
	@Autowired
	YgCouponService ygCouponService;
	@Autowired
	YgUserService ygUserService;
	@Autowired
	YgCouponDetailService ygCouponDetailService;
	@Autowired
	YgTaskTimeService ygTaskTimeService;
	@Autowired
	WxMpAuthorityService wxMpAuthorityService;
	@Autowired
	WxMpMessageService wxMpMessageService;

	private void check(YgOrder order, YgCoupon coupon, Date endDate, List<YgCouponDetail> detailList, String trueName) {
		int count = 0;
		if (order.getTotalPrice().doubleValue() >= 200d && order.getTotalPrice().doubleValue() < 400d) {
			count = 1;
		} else if (order.getTotalPrice().doubleValue() >= 400d && order.getTotalPrice().doubleValue() < 600d) {
			count = 2;
		} else if (order.getTotalPrice().doubleValue() >= 600d) {
			count = 3;
		}

		if (count > 0) {
			YgUser user = ygUserService.findById(order.getUserId());
			this.addCoupon(user, coupon, endDate, count, detailList, trueName);
		}
	}

	private void addCoupon(YgUser user, YgCoupon coupon, Date endDate, int count, List<YgCouponDetail> detailList, String trueName) {
		count = count > 3 ? 3 : count;

		for (int i = 0; i < count; i++) {

			YgCouponDetail detail = new YgCouponDetail();
			detail.setCouponBatchId(coupon.getId());
			detail.setCouponCode(YgStringUtils.getRandomString(12).toUpperCase());
			detail.setUserId(user.getId());
			detail.setUserName(user.getUserName());
			detail.setFaceValue(coupon.getFaceValue());
			detail.setLeadTime(new Date());
			detail.setStartDate(endDate);
			detail.setEndDate(endDate);
			detail.setExecutor(trueName);
			detail.setUseStatus(CouponStatus.Received);
			detail.setRemark("补双11满减券");
			detailList.add(detail);

		}

	}

	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	@Override
	public void sendCoupon1111(List<YgOrder> list, YgCoupon coupon, Date endDate, String trueName) {

		if (!CollectionUtils.isEmpty(list)) {
			List<YgCouponDetail> detailList = new ArrayList<YgCouponDetail>();
			List<YgCouponDetail> addList = new ArrayList<YgCouponDetail>();
			for (YgOrder order : list) {
				if (order.getPaidTime() != null) {
					this.check(order, coupon, endDate, detailList, trueName);
				}
			}
			Map<Long, List<YgCouponDetail>> maps = detailList.stream().collect(Collectors.groupingBy(YgCouponDetail::getUserId));
			for (Entry<Long, List<YgCouponDetail>> map : maps.entrySet()) {
				Long key = map.getKey();
				List<YgCouponDetail> values = map.getValue();
				List<YgCouponDetail> hasList = ygCouponDetailService.findByCouponBatchId(232L, key);
				int count = 3 - hasList.size();
				if (count > 0) {
					count = count > values.size() ? values.size() : count;
					for (int i = 0; i < count; i++) {
						addList.add(values.get(i));
					}
				}
			}
			ygCouponDetailService.addPostponeCouponDetailBatch(addList);
		}
	}

	@Override
	public void repairBalanceByOrderId(Long... orderIds) {
		Date date = new Date();
		List<YgUserBalanceDetail> inComeList = ygUserBalanceDetailService.findNoBalanceInComeListByOrderIds(orderIds);

		List<YgReturnOrder> roList = ygReturnOrderService.find(orderIds);
		Map<Long, List<YgReturnOrder>> returnMap = null;
		if (!CollectionUtils.isEmpty(roList)) {
			returnMap = roList.stream().collect(Collectors.groupingBy(YgReturnOrder::getOrderId));
		}
		List<YgUserBalanceDetail> list = new ArrayList<YgUserBalanceDetail>();
		Set<Long> userIds = new HashSet<Long>();
		for (YgUserBalanceDetail inCome : inComeList) {

			BigDecimal refundPrice = this.getRefundPrice(Long.parseLong(inCome.getOrderId()), returnMap);
			if (inCome.getOrderPrice().compareTo(refundPrice) > 0) {

				YgUserBalanceDetail d = new YgUserBalanceDetail();
				d.setUserId(inCome.getUserId());
				d.setIncomePayPrice(new BigDecimal(0));
				d.setBalancePrice(inCome.getIncomePayPrice());
				d.setPriceType(BalanceType.Balance);
				d.setOperationType(inCome.getOperationType());
				d.setOperation(inCome.getOperation());
				d.setOrderId(inCome.getOrderId());
				d.setCommissionRate(inCome.getCommissionRate());
				d.setOrderPrice(inCome.getOrderPrice());
				d.setCommissionStatus(CommissionStatus.PayError);
				d.setRemark("可提现。");
				d.setCreateTime(date);
				d.setRebateType(inCome.getRebateType());
				d.setCreateBy("repair");
				list.add(d);
				userIds.add(d.getUserId());
			}
		}
		for (Long orderId : orderIds) {
			YgOrder order = ygOrderService.findByOrderId(orderId);
			BigDecimal refundPrice = this.getRefundPrice(orderId, returnMap);
			BigDecimal lastPrice = order.getTotalPrice().subtract(refundPrice);
			if (lastPrice.compareTo(new BigDecimal("0.00")) > 0) {

				String rewardOrder = ygUserBalanceDetailMapper.selectBalanceDetailByOrderId(BalanceType.Balance, RebateType.Reward, order.getOrderId() + "");
				if (rewardOrder == null) {
					// 用户下单，发货后15天，如果没有退货，奖励用户成长基金。
					YgUserBalanceDetail rewardDetail = new YgUserBalanceDetail();
					YgUser user = ygUserService.findById(order.getUserId());
					BigDecimal rate = new BigDecimal(0.01);
					if (user.getLevel() == 10) {
						rate = new BigDecimal(0.02);
					}
					rewardDetail.setBalancePrice(lastPrice.multiply(rate).setScale(2, BigDecimal.ROUND_HALF_UP)); 
					rewardDetail.setOperation(OperationType.Reward.getTitle());
					rewardDetail.setOperationType(OperationType.Reward);
					rewardDetail.setIncomePayPrice(new BigDecimal(0));
					rewardDetail.setOrderId(order.getOrderId() + "");
					rewardDetail.setCreateTime(new Date());
					rewardDetail.setCreateBy("repair");
					rewardDetail.setPriceType(BalanceType.Balance);
					rewardDetail.setOrderPrice(order.getTotalPrice());
					rewardDetail.setUserId(order.getUserId());
					rewardDetail.setRebateType(RebateType.Reward);
					rewardDetail.setCommissionRate(new BigDecimal("0.01"));
					list.add(rewardDetail);
					userIds.add(order.getUserId());
				}
			}
		}
		ygUserBalanceService.addBalacneDetailByBatch(list);
		List<Long> userList = new ArrayList<Long>(userIds);
		List<YgUserBalance> balanceList = ygUserBalanceDetailMapper.findUbdSumByUserIds(userList, BalanceType.Balance);
		ygUserBalanceService.updateUserBalancePrice(balanceList);

	}

	private BigDecimal getRefundPrice(Long orderId, Map<Long, List<YgReturnOrder>> returnMap) {

		BigDecimal refundPrice = new BigDecimal("0.00");
		if (!CollectionUtils.isEmpty(returnMap)) {
			List<YgReturnOrder> ros = returnMap.get(orderId);
			refundPrice = ros.stream().map(ro -> ro.getRefundPrice()).reduce(new BigDecimal("0.00"), (a, b) -> a.add(b));
		}
		return refundPrice;
	}

	@Override
	public List<YgUser> send11buquan(Boolean isSubscribe) {
		return ygUserService.send11buquan(isSubscribe);
	}
}
